package cn.xuqiudong.demo.dubbo.common.filter;

import cn.xuqiudong.demo.dubbo.common.constant.DubboConstant;
import cn.xuqiudong.demo.dubbo.common.tools.DubboTools;
import cn.xuqiudong.demo.dubbo.common.tools.SpringSessionUtil;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.session.Session;
import org.springframework.util.StringUtils;

/**
 * 描述: dubbo  服务端filter， 加入traceId 信息(用于log4j日志链路追加，tranceId里包含sessionId 用于获取session信息)
 * @author Vic.xu
 * @since 2022-01-24 10:50
 */
@Activate(group = CommonConstants.PROVIDER)
public class ProviderTraceFilter implements Filter {

    private Logger logger = LoggerFactory.getLogger(ProviderTraceFilter.class);

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        intiFromAttachment(invocation);
        try {
            return invoker.invoke(invocation);

        } finally {
            DubboTools.removeLocalTranceId();
            //DubboTools.removeLocalSessionInfo();
        }
    }


    private void intiFromAttachment(Invocation invocation) {
        String tranceId = invocation.getAttachment(DubboTools.TRACE_ID);
        if (!StringUtils.hasText(tranceId)) {
            return;
        }
        logger.info("set tranceId = {} to slf4j MDC", tranceId);
        DubboTools.setLocalTranceId(tranceId);
        //存入到slf4j 设置了日志打印格式用作日志链路追踪
        MDC.put(DubboTools.TRACE_ID, tranceId);
        //获取session信息
        findSessionInfo(tranceId);
    }

    public void findSessionInfo(String sessionId) {
        Session session = SpringSessionUtil.springSession(sessionId);
        if (session == null) {
            logger.info("there is no session with sessionId: {}", sessionId);
            return;
        }
        // TODO  强转为实际类型 然后保存到当前线程
        Object sessionInfo = session.getAttribute(DubboConstant.SESSION_INFO);
        logger.info("sessionInfo：{}" , sessionInfo);
        //DubboTools.setLocalSessionInfo(sessionInfo);
    }
}
